# 导入系统模块
import os
import json
import uuid
import logging
# 导入Django HTTP响应相关模块
from django.http import JsonResponse, HttpResponse, HttpResponseBadRequest
# 导入Django CSRF和登录装饰器
from django.views.decorators.csrf import csrf_exempt
from django.contrib.auth.decorators import login_required
# 导入Django设置
from django.conf import settings
# 导入模型
from core.models.chapter import Chapter
from core.models.knowledge_point import KnowledgePoint
# 导入图片处理和API调用函数
from .image_processing import image_to_base64, call_openai_api_question_and_answer

# 初始化日志记录器
logger = logging.getLogger(__name__)

@login_required
def ajax_chapters(request):
    """
    获取指定学科的章节列表
    
    参数:
        request: HTTP请求对象，包含学科ID参数
    
    返回:
        JsonResponse: 包含章节ID和名称的JSON数据
    """
    try:
        # 获取学科ID参数
        subject_id = request.GET.get("subject_id")
        logger.debug(f"收到章节请求，subject_id: {subject_id}")
        # 查询指定学科的章节，并按顺序排序
        chapters = Chapter.objects.filter(subject_id=subject_id).order_by("order")
        logger.debug(f"查询到章节数量: {chapters.count()}")
        # 构造返回数据
        data = [{"id": c.id, "name": c.name} for c in chapters]
        logger.debug(f"返回章节数据: {data}")
        # 返回JSON数据
        return JsonResponse(data, safe=False)
    except Exception as e:
        # 记录错误日志
        logger.error(f"章节请求处理错误: {str(e)}", exc_info=True)
        # 返回错误响应
        return JsonResponse({"error": str(e)}, status=500)

@login_required
def ajax_knowledge_points(request):
    """
    获取指定章节的知识点列表
    
    参数:
        request: HTTP请求对象，包含章节ID参数
    
    返回:
        JsonResponse: 包含知识点ID和名称的JSON数据
    """
    # 获取章节ID参数
    chapter_id = request.GET.get("chapter_id")
    logger.info(f"ajax_knowledge_points called with chapter_id: {chapter_id}")
    # 查询指定章节的知识点，并按顺序排序
    knowledge_points = KnowledgePoint.objects.filter(chapter_id=chapter_id).order_by(
        "order"
    )
    logger.info(
        f"Found {knowledge_points.count()} knowledge points for chapter_id: {chapter_id}"
    )
    # 构造返回数据
    data = [{"id": p.id, "name": p.name} for p in knowledge_points]
    # 返回JSON数据
    return JsonResponse(data, safe=False)

@login_required
@csrf_exempt
def upload_image(request):
    """
    处理图片上传请求
    
    参数:
        request: HTTP请求对象，包含要上传的图片文件
    
    返回:
        JsonResponse: 包含上传状态和图片URL的JSON数据
    """
    if request.method == "POST":
        logger.info(f"Image upload request received: {request.FILES}")

        # 检查是否包含图片文件
        if not request.FILES.get("upload"):
            logger.error("No image file found in request")
            return JsonResponse(
                {"uploaded": False, "error": {"message": "未找到图片文件"}}
            )

        # 获取上传的图片文件
        image_file = request.FILES["upload"]

        # 验证文件类型
        allowed_types = [
            "image/jpeg",
            "image/png",
            "image/gif",
            "image/bmp",
            "image/jpg",
            "image/tiff",
            "image/svg+xml",
        ]
        file_ext = (
            image_file.name.split(".")[-1].lower() if "." in image_file.name else ""
        )
        allowed_extensions = ["jpg", "jpeg", "png", "gif", "bmp", "tiff", "svg"]
        # 同时验证MIME类型和文件扩展名
        if (
            image_file.content_type not in allowed_types
            and file_ext not in allowed_extensions
        ):
            logger.error(
                f"Invalid file type: {image_file.content_type}, extension: {file_ext}"
            )
            return JsonResponse(
                {
                    "uploaded": False,
                    "error": {
                        "message": "不支持的文件类型，仅允许JPG、JPEG、PNG、GIF、BMP、TIFF、SVG"
                    },
                }
            )

        # 生成唯一文件名（避免重复）
        filename = f"{uuid.uuid4()}.{image_file.name.split('.')[-1].lower()}"

        # 保存路径
        save_path = os.path.join(settings.MEDIA_ROOT, "uploaded_images", filename)
        # 确保目录存在
        os.makedirs(os.path.dirname(save_path), exist_ok=True)

        try:
            # 保存图片
            with open(save_path, "wb+") as f:
                for chunk in image_file.chunks():
                    f.write(chunk)

            # 验证文件是否成功保存
            if not os.path.exists(save_path):
                raise Exception("File not saved after writing")

            # 返回图片的访问URL
            image_url = f"{settings.MEDIA_URL.rstrip('/')}/uploaded_images/{filename}"
            logger.info(f"Image uploaded successfully: {image_url}")
            return JsonResponse({"uploaded": True, "url": image_url})
        except Exception as e:
            logger.error(f"Error uploading image: {str(e)}", exc_info=True)
            return JsonResponse(
                {"uploaded": False, "error": {"message": f"上传失败: {str(e)}"}}
            )

    # 非POST请求处理
    logger.warning("Image upload request with invalid method")
    return JsonResponse({"uploaded": False, "error": {"message": "无效的请求方法"}})

def get_mistake_text(request):
    """
    处理图片分析请求，获取错题文本
    
    参数:
        request: HTTP请求对象，包含图片路径和分析类型参数
    
    返回:
        JsonResponse: 包含分析结果的JSON数据
    """
    import base64
    from openai import OpenAI

    image_path = None  # 初始化图片路径变量

    # 确保只接受POST请求
    if request.method != 'POST':
        return JsonResponse({'error': '只支持POST请求'}, status=405)

    try:
        # 从请求中获取图片路径或内容
        image_path = request.POST.get('image_url')
        only_question = request.POST.get('only_question')

        # 检查图片文件是否存在
        if not os.path.exists(image_path):
            return JsonResponse({'error': f'图片文件不存在: {image_path}'}, status=400)

        # 检查图片格式
        valid_formats = ['.png', '.jpg', '.jpeg']
        file_ext = os.path.splitext(image_path)[1].lower()
        if file_ext not in valid_formats:
            return JsonResponse({'error': f'不支持的图片格式: {file_ext}，仅支持 {valid_formats}'}, status=400)

        # 转换图片为Base64
        image_base64, mime_type = image_to_base64(image_path)
        if not image_base64:
            return JsonResponse({'error': '图片转换失败'}, status=500)

        # 验证Base64编码
        try:
            decoded_data = base64.b64decode(image_base64)
        except Exception as e:
            return JsonResponse({'error': f'Base64编码无效: {str(e)}'}, status=400)

        # 从配置文件导入OpenAI设置
        from testsys.settings import OPENAI_BASE_URL, OPENAI_API_KEY

        # 初始化OpenAI客户端
        client = OpenAI(
            base_url=OPENAI_BASE_URL,
            api_key=OPENAI_API_KEY,
        )

        # 调用API进行图片分析
        response=call_openai_api_question_and_answer(client, mime_type, image_base64)

        # 提取响应内容
        if response.choices and len(response.choices) > 0:
            content = response.choices[0].message.content
            return JsonResponse({'result': content})
        else:
            return JsonResponse({'error': '未获取到识别结果'}, status=500)

    except Exception as e:
        # 处理异常情况
        return JsonResponse({'error': f'服务器内部错误: {str(e)}'}, status=500)
    finally:
        # 执行结束后删除图片
        if image_path and os.path.exists(image_path):
            try:
                os.remove(image_path)
                print(f"图片 {image_path} 已成功删除")
            except Exception as e:
                print(f"删除图片时发生错误: {str(e)}")

def analyze_image(request):
    """
    分析图片中的题目内容
    
    参数:
        request: HTTP请求对象，包含图片URL和分析类型参数
    
    返回:
        JsonResponse: 包含分析结果的JSON数据
    """
    import base64
    from openai import OpenAI

    # 确保只接受POST请求
    if request.method != 'POST':
        return JsonResponse({'error': '只支持POST请求'}, status=405)

    try:
        # 从请求中获取图片URL和only_question参数
        image_url = request.POST.get('image_url')
        only_question = request.POST.get('only_question') == 'true'

        # 检查图片URL是否存在
        if not image_url:
            return JsonResponse({'error': '未提供图片URL'}, status=400)

        # 从URL中提取图片路径
        media_url = settings.MEDIA_URL
        if image_url.startswith(media_url):
            image_path = os.path.join(settings.MEDIA_ROOT, image_url[len(media_url):])
        else:
            return JsonResponse({'error': '无效的图片URL'}, status=400)

        # 检查图片文件是否存在
        if not os.path.exists(image_path):
            return JsonResponse({'error': f'图片文件不存在: {image_path}'}, status=400)

        # 检查图片格式
        valid_formats = ['.png', '.jpg', '.jpeg']
        file_ext = os.path.splitext(image_path)[1].lower()
        if file_ext not in valid_formats:
            return JsonResponse({'error': f'不支持的图片格式: {file_ext}，仅支持 {valid_formats}'}, status=400)

        # 转换图片为Base64
        image_base64, mime_type = image_to_base64(image_path)
        if not image_base64:
            return JsonResponse({'error': '图片转换失败'}, status=500)

        # 验证Base64编码
        try:
            decoded_data = base64.b64decode(image_base64)
        except Exception as e:
            return JsonResponse({'error': f'Base64编码无效: {str(e)}'}, status=400)

        # 从配置文件导入OpenAI设置
        from testsys.settings import OPENAI_BASE_URL, OPENAI_API_KEY

        # 初始化OpenAI客户端
        client = OpenAI(
            base_url=OPENAI_BASE_URL,
            api_key=OPENAI_API_KEY,
        )

       
        response = call_openai_api_question_and_answer(client, mime_type, image_base64)

        # 提取响应内容
        if response.choices and len(response.choices) > 0:
            content = response.choices[0].message.content
            return JsonResponse({'success': True, 'content': content})
        else:
            return JsonResponse({'error': '未获取到识别结果'}, status=500)

    except Exception as e:
        # 处理异常情况
        return JsonResponse({'error': f'服务器内部错误: {str(e)}'}, status=500)
    finally:
        # 执行结束后删除图片
        if image_path and os.path.exists(image_path):
            try:
                os.remove(image_path)
                print(f"图片 {image_path} 已成功删除")
            except Exception as e:
                print(f"删除图片时发生错误: {str(e)}")